///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.gaugesClasses.rectangular
{
  import ilog.gauges.gaugesClasses.GaugeElement;
  import ilog.gauges.rectangular.RectangularGauge;

  /**
   * The <code>RectangularGaugeElement</code> class is the base class for the visual 
   * elements of rectangular gauges. This class allows you to define the position
   * and size of the elements using <code>x</code>, <code>y</code>, <code>width</code>, 
   * and <code>height</code> properties expressed in percentages or absolute values. 
   * The <code>RectangularGauge</code> sets the position and size of all the visual 
   * elements based on theses values and on the <code>area</code> property.
   * This property defines five areas to layout the elements into:
   * <ul>
   *   <li>the left area</li>
   *   <li>the right area</li>
   *   <li>the top area</li>
   *   <li>the bottom area</li>
   *   <li>the center area (default)</li>
   * </ul>
   * <p>
   * The side areas are commonly used for fixed-size objects, such as labels
   * or indicators. The center position, taking the remaining place, is used
   * by the core gauge elements, like scale, track, or value renderers. 
   * </p>
   * <p>
   * First, the side areas are sized so that elements in the left and right areas on one 
   * hand, top and bottom areas on the other hand, can fit respectively their 
   * measured width and height in them.
   * </p>
   * <p>
   * Then the elements in the side areas are positioned and sized according to 
   * their <code>x</code>, <code>y</code>, <code>width</code>, and <code>height</code>
   * properties. The percentage values are relative to the bounds of the corresponding
   * area computed in the first step.
   * </p>
   * <p>
   * Lastly, the remaining area in the center of the gauge is used to lay out the
   * elements in this area. If the gauge has no explicit width, either in 
   * pixels or in percentage, the center area will have a width computed from the 
   * measured width of the elements in this area. Similarly, if the gauge has no 
   * explicit height, either in pixels or in percentage, the center area will have a 
   * height computed from the measured height of the elements in this area. If the 
   * gauge has an explicit width (or height), the elements in the center take as 
   * much width (or height) as is available. They are never bigger than their 
   * <code>maxWidth</code> (or <code>maxHeight</code>), so you can use these 
   * properties to avoid scaling them too much, if there is too much space
   * available in the center.
   * </p>
   * <p>
   * The <code>x</code>, <code>y</code>, <code>width</code>, and <code>height</code> 
   * properties of an element, when expressed in percentages, are relative to the 
   * area bounds of the given element.
   * </p> 
   * @mxml
   *  
   * <p>The <code>&lt;ilog:RectangularGaugeElement&gt;</code> tag inherits all 
   * the properties of its parent classes and adds the following properties:</p>
   *  
   * <pre>
   * &lt;ilog:CircularGaugeElement
   *   <strong>Properties</strong>
   *   x="0%"
   *   y="0%"
   *   width="100%"
   *   height="100%"
   *   area="center|left|right|top|bottom"  
   *  /&gt;
   * </pre>
   * 
   * @see ilog.gauges.rectangle.RectangularGauge
   * 
   */  
  public class RectangularGaugeElement extends GaugeElement
  {
    /**
     * Constructor.
     */
    public function RectangularGaugeElement()
    {
      super();
      percentWidth = 100;
      percentHeight = 100;      
    }
      
    /**
     * The <code>RectangularGauge</code> holding this gauge element.
     */       
    public function get gauge():RectangularGauge
    {
      return owner as RectangularGauge;
    }
    
    private var _percentX:Number = 0;
    
    [Inspectable(environment="none")] 

    /**
     * Number that specifies the <code>x</code> position of an element as a percentage
     * of its corresponding area size. Allowed values are 0-100. 
     * Setting the <code>x</code> or <code>explicitX</code> properties 
     * resets this property to <code>NaN</code>.
     *
     * <p>This property returns a numeric value only if the property was
     * previously set. It does not reflect the exact position of the component
     * in percent.</p>
     * 
     * @default 0
     */    
    public function set percentX(value:Number):void
    {
      if (_percentX == value)
        return

      if (!isNaN(value))
        _explicitX = NaN;
              
      _percentX = value;
    }
    
    /**
     * @private
     */
    public function get percentX():Number
    {
      return _percentX; 
    }
    
    private var _explicitX:Number;

    [Inspectable(environment="none")] 
    
    /**
     * Number that specifies the explicit <code>x</code> position of the element,
     * in pixels, in its corresponding area coordinates.
     *
     * <p>This value is used by the gauge to compute
     * the position of the element.</p>
     * 
     * <p>Setting the <code>x</code> property also sets this property to
     * the specified <code>x</code> value.</p>
     */        
    public function set explicitX(value:Number):void
    {
      if (_explicitX == value)
        return;

      if (!isNaN(value))
        _percentX = NaN;
      
      _explicitX = value;
    }

    /**
     * @private
     */    
    public function get explicitX():Number
    {
      return _explicitX;
    }
    
    [Inspectable(category="General")]
    [PercentProxy("percentX")]

    /**
     * Number that specifies the <code>x</code> position of the element, in pixels,
     * in its corresponding area coordinates.
     *  
     * <p><strong>Note:</strong> You can specify a percentage value in the MXML
     * <code>x</code> attribute, such as <code>x="10%"</code>,
     * but you cannot use a percentage value in the <code>x</code>
     * property in ActionScript.
     * Use the <code>percentX</code> property instead.</p>
     */    
    public override function set x(value:Number):void
    {
      if (explicitX != value) {
        explicitX = value;        
      } 
      if (super.x != value) {
        super.x = value;
      }
    }
    
    private var _percentY:Number = 0;

    [Inspectable(environment="none")]

    /**
     * Number that specifies the <code>y</code> position of an element as a percentage
     * of its corresponding area size. Allowed values are 0-100. 
     * Setting the <code>y</code> or <code>explicitY</code> properties 
     * resets this property to <code>NaN</code>.
     *
     * <p>This property returns a numeric value only if the property was
     * previously set. It does not reflect the exact position of the component
     * in percent.</p>
     * 
     * @default 0
     */      
    public function set percentY(value:Number):void
    {
      if (_percentY == value)
        return

      if (!isNaN(value))
        _explicitY = NaN;
      
      _percentY = value;
    }
    
    /**
     * @private
     */
    public function get percentY():Number
    {
      return _percentY; 
    }
    
    private var _explicitY:Number;
    
   [Inspectable(environment="none")] 
   
    /**
     * Number that specifies the explicit <code>y</code> position of the element,
     * in pixels, in its corresponding area coordinates.
     *
     * <p>This value is used by the gauge to compute
     * the position of the element.</p>
     * 
     * <p>Setting the <code>y</code> property also sets this property to
     * the specified <code>y</code> value.</p>
     */        
    public function set explicitY(value:Number):void
    {
      if (_explicitY == value)
        return;

      if (!isNaN(value))
        _percentY = NaN;
              
      _explicitY = value;
    }
    
    /**
     * @private
     */
    public function get explicitY():Number
    {
      return _explicitY;
    }
    
    [Inspectable(category="General")]
    [PercentProxy("percentY")]

    /**
     * Number that specifies the <code>y</code> position of the element, in pixels,
     * in its corresponding area coordinates.
     *  
     * <p><strong>Note:</strong> You can specify a percentage value in the MXML
     * <code>y</code> attribute, such as <code>y="10%"</code>,
     * but you cannot use a percentage value in the <code>y</code>
     * property in ActionScript.
     * Use the <code>percentY</code> property instead.</p>
     */      
    public override function set y(value:Number):void
    {
      if (explicitY != value) {
        explicitY = value;        
      } 
      if (super.y != value) {
        super.y = value;
      }
    }    
    
    private var _area:String = "center";
    
    [Inspectable(category="Gauge", defaultValue="horizontal", enumeration="center,top,bottom,left,right", type="String")]    
       
    /**
     * The area into which the element must be positioned by the gauge.
     * The possible values are:
     * <ul>
     *   <li><code>"center"</code> -
     *   Put the element in the center of the gauge.</li>
     *
     *   <li><code>"left"</code> -
     *   Put the element to the left of the gauge.</li>
     *
     *   <li><code>"right"</code> -
     *   Put the element to the right of the gauge.</li>
     * 
     *   <li><code>"top"</code> -
     *   Put the element at the top of the gauge.</li>
     *
     *   <li><code>"bottom"</code> -
     *   Put the element at the bottom of the gauge.</li>
     * </ul>
     * 
     * @default "center"
     */
    public function set area(value:String):void
    {
      _area = value;
    }
    
    /**
     * @private
     */
    public function get area():String
    {
      return _area;
    }
  }
}
